package cn.wps.moffice.framework.thread;

import android.os.Handler;
import android.os.Looper;
import cn.wps.moffice.framework.util.KRunnableTriple;

public class KThreadUtil {
	
	static private class WaitRunnable implements Runnable
	{
		private static WaitRunnable _listHead;
		private WaitRunnable _next;
		
		private volatile boolean done;

		synchronized
		public static WaitRunnable obtain()
		{
			WaitRunnable runnable = _listHead;
			if (null == runnable)
				runnable = new WaitRunnable();
			else
				_listHead = runnable._next;
			runnable._next = null;
			return runnable;
		}
		
		synchronized
		private static void recycle(WaitRunnable runnable)
		{
			runnable._next = _listHead;
			_listHead = runnable;
		}
		
		@Override
		synchronized 
		public void run() {
			done = true;
			notifyAll();
			recycle(this);
		}
		
		synchronized
		public void waitRunInThread(Handler handler, Runnable runnable)
		{
			done = false;
			handler.post(KRunnableTriple.obtain(runnable, this));
			while (!done)
			{
				try {
					wait();
	            } catch (InterruptedException e) {
	            }
			}
		}
	}

	private static Handler sMainHandler;

	public static boolean isUiThread()
	{
		return Thread.currentThread().getId() == Looper.getMainLooper().getThread().getId();
	}
	
	static private void __runInThread(Handler handler, Runnable runnable, boolean wait)
	{
		if (Thread.currentThread() == handler.getLooper().getThread())
		{
			if (wait)
			{
				runnable.run();
			}
			else
			{
				handler.post(runnable);
			}
			return;
		}
		
		if (!wait)
		{
			handler.post(runnable);
			return;
		}
		
		WaitRunnable.obtain().waitRunInThread(handler, runnable);
	}
	
	static public Handler getMainHandler()
	{
		if (null == sMainHandler)
			sMainHandler = new Handler(Looper.getMainLooper());
		return sMainHandler;
	}
	
	static public void runInUiThread(Runnable runnable, boolean wait)
	{
		__runInThread(getMainHandler(), runnable, wait);
	}
	
	static public void runInHandlerThread(Handler handler, Runnable runnable, boolean wait)
	{
		__runInThread(handler, runnable, wait);
	}
}
